#!/bin/bash

#链接文件
source /etc/profile
TIME_STAMP=`date '+%Y-%m-%d %H:%M:%S'`
WHO=`whoami`

#java虚拟机启动参数
#通过http://xxfox.perfma.com/jvm/check来检查参数的合理性
JAVA_OPTS=" -server -Xms256m -Xmx512m -Xmn512m -Xss256k -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m"
JAVA_OPTS="$JAVA_OPTS -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=5 -XX:GCTimeRatio=19 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC"
JAVA_OPTS="$JAVA_OPTS -XX:+UseCMSCompactAtFullCollection -XX:-CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=70"
JAVA_OPTS="$JAVA_OPTS -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintTenuringDistribution -XX:+PrintClassHistogram -XX:+PrintGCDetails "
JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5"
JAVA_OPTS="$JAVA_OPTS -XX:GCLogFileSize=10M -Xloggc:/data/logs/wp-ibitauto-utils-starter/gc.gclog"
JAVA_OPTS="$JAVA_OPTS -XX:-OmitStackTraceInFastThrow"
JAVA_OPTS="$JAVA_OPTS -Dapp.name=wp-ibitauto-utils-starter"
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8 -Duser.timezone=GMT+8"

APP_OPTS="--spring.profiles.active=uat"


#JAR包路径:
APP_NAME=wp-ibitauto-utils-starter.jar
#服务暂停后等待时间,默认为120秒
PAUSE_WAIT=120
#进程停止需等待多少秒
SHUTDOWN_WAIT=30

workdir=$(cd $(dirname $0); pwd)


echo "======================================================================================"
echo "WHO: "$WHO
echo "TIME_STAMP: "$TIME_STAMP
echo "java "$JAVA_OPTS" -jar "$workdir"/"$APP_NAME" "$APP_OPTS
echo "======================================================================================"


#使用说明，用来提示输入参数
usage() {
    echo "Usage: sh 执行脚本.sh [start|stop|restart|status]"
    exit 1
}

#检查程序是否在运行
checkpid(){
  pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' `
  if [ ! -z "${pid}" ]; then
   return 0 # 0=true
  fi

  return 1 # 1=false
}

#检查程序端口是否已启动
checkport() {
  if checkpid; then
    port=$(netstat -ntlp | grep $pid | awk '{printf $4}' | cut -d':' -f4)
    if [ ! -z "${port}" ]; then
     return 0 # 0=true
    else
      return 1 # 1=false
    fi
  else
    echo "${APP_NAME} is not running!"
    return 1
  fi
}

checktcp() {
  echo "start check connections, $SECONDS."

  if checkport; then
    local count=0;
    until [ `netstat -ntp | grep ESTABLISHED | awk -v port=":$port" '$4~port{print}' | wc -l` = '0' ] || [ ${count} -gt ${PAUSE_WAIT} ]
    do
      if [ `expr ${count} % 5` -eq 0 ]; then
        echo "waiting for connections disconnect!"
      fi
      sleep 1
      let count=$count+1;
    done

    if [ ${count} -gt ${PAUSE_WAIT} ]; then
      echo "wait for ${PAUSE_WAIT} seconds, still have connetion"
      #打印所有的连接
      netstat -ntp | grep ESTABLISHED | awk -v port=":$port" '$4~port{print}'
    fi
  fi
  echo "end check connections, $SECONDS."
}

#启动方法
start(){
  echo "starting ..."

  if checkpid; then
    echo "${APP_NAME} is already running. pid=${pid} ."
  else
    nohup java $JAVA_OPTS -jar $workdir/$APP_NAME $APP_OPTS > /dev/null 2>&1 &
  fi
}


#停止方法
stop(){
  echo "stopping ..."

  if checkpid; then
    #停止分为3个步骤：暂停、检测tcp连接、停止进程
    pause
    checktcp
    kill $pid

    local kwait=$SHUTDOWN_WAIT
    local count=0;
    until [ `ps -p $pid | grep -c $pid` = '0' ] || [ $count -gt $kwait ]
    do
      echo "waiting for processes to exit";
      sleep 1
      let count=$count+1;
    done

    if [ $count -gt $kwait ]; then
      echo "killing processes didn't stop after $SHUTDOWN_WAIT seconds"
      kill -9 $pid
    fi

    echo "${APP_NAME} stopped."
  else
    echo "${APP_NAME} is not running"
  fi
}

#输出运行状态
status(){
  if checkpid; then
    echo "${APP_NAME} is running. pid is ${pid}"
  else
    echo "${APP_NAME} is NOT running."
  fi
}

#重启
restart(){
  stop
  start
}

#根据输入参数，选择执行对应方法，不输入则执行使用说明
case "$1" in
  "start")
    start
    ;;
  "stop")
    stop
    ;;
  "status")
    status
    ;;
  "restart")
    restart
    ;;
  "check")
    checktcp
    ;;
  *)
    usage
    ;;
esac
